﻿using System;
using System.Diagnostics;
using System.Runtime.Serialization;
using System.Xml.Serialization;
using ElectronicCommerce.Framework.Utility;

namespace ElectronicCommerce.Framework.Diagnostics
{
    /// <summary>
    /// 提供特定于线程和进程的跟踪事件数据。
    /// </summary>
    [Serializable]
    [XmlRoot("TraceEventInfo")]
    [DataContract(Name = "TraceEventInfo")]
    public class TraceEventInfo
    {
        #region [ Fields ]

        private string source = string.Empty;
        private string category = string.Empty;
        private string subCategory = string.Empty;
        private string eventCode = string.Empty;
        private TraceEventType type = TraceEventType.Information;
        private DateTime dateTime = DateTime.Now;
        private long timeStamp = -1L;
        // Server Info
        private string hostName = string.Empty;
        private string hostUser = string.Empty;
        private string appDomainName = string.Empty;
        private string processId;
        private string processName;
        private string threadId;
        private string threadName;
        private string stackTrace;
        // Client Info
        private string fromIP = string.Empty;
        private string appUser = string.Empty;

        private string title = string.Empty;
        private string message = string.Empty;

        private ExtendedPropertyCollection extendedProperties;

        internal bool dateTimeInitialized = false;
        internal bool timeStampInitialized = false;
        internal bool hostNameInitialized = false;
        internal bool appDomainNameInitialized = false;
        internal bool processInitialized = false;
        internal bool threadIdInitialized = false;
        internal bool threadNameInitialized = false;
        internal bool stackTraceInitialized = false;
        internal bool hostUserInitialized = false;

        #endregion

        #region [ Properties ]

        /// <summary>
        /// 事件信息唯一性代码。
        /// </summary>
        [XmlAttribute("code")]
        [DataMember]
        public string Code
        {
            get { return this.eventCode; }
            set { this.eventCode = value; }
        }

        /// <summary>
        /// 获取标题。
        /// </summary>
        [DataMember]
        public string Title
        {
            get { return this.title; }
            set { this.title = value; }
        }

        /// <summary>
        /// 跟踪详细信息。
        /// </summary>
        [DataMember]
        public string Message
        {
            get { return this.message; }
            set { this.message = value; }
        }

        /// <summary>
        /// 事件源。
        /// </summary>
        [DataMember]
        public string Source
        {
            get { return this.source; }
            set { this.source = value; }
        }

        /// <summary>
        /// 跟踪事件信息所属目录。如果没有设定则为空。
        /// </summary>
        [DataMember]
        public string Category
        {
            get { return this.category; }
            set { this.category = value; }
        }

        /// <summary>
        /// 跟踪事件信息所属目录。如果没有设定则为空。
        /// </summary>
        [DataMember]
        public string SubCategory
        {
            get { return this.subCategory; }
            set { this.subCategory = value; }
        }

        /// <summary>
        /// 跟踪事件类型。
        /// </summary>
        [XmlAttribute("type")]
        [DataMember]
        public TraceEventType Type
        {
            get { return this.type; }
            set { this.type = value; }
        }

        /// <summary>
        /// 获取事件跟踪发生的日期和时间。
        /// </summary>		
        [DataMember]
        public DateTime DateTime
        {
            get
            {
                this.EnsureDateTimeInitialized();
                return this.dateTime;
            }
            set
            {
                this.dateTime = value;
                this.dateTimeInitialized = true;
            }
        }

        /// <summary>
        /// 获取计时器机制中的当前最小时间单位数。 
        /// </summary>
        [DataMember]
        public long Timestamp
        {
            get
            {
                this.EnsureTimeStampInitialized();
                return this.timeStamp;
            }
            set
            {
                this.timeStamp = value;
                this.timeStampInitialized = true;
            }
        }

        /// <summary>
        /// 获取服务器名称。
        /// </summary>
        [DataMember]
        public string HostName
        {
            get
            {
                this.EnsureHostNameInitialized();
                return this.hostName;
            }
            set
            {
                this.hostName = value;
                this.hostNameInitialized = true;
            }
        }

        /// <summary>
        /// 服务器登录用户。
        /// </summary>
        [DataMember]
        public string HostUser
        {
            get
            {
                this.EnsureHostUserInitialized();
                return this.hostUser;
            }
            set
            {
                this.hostUser = value;
                this.hostUserInitialized = true;
            }
        }

        /// <summary>
        /// 获取当前域名。
        /// </summary>
        [DataMember]
        public string AppDomainName
        {
            get
            {
                this.EnsureAppDomainNameInitialized();
                return this.appDomainName;
            }
            set
            {
                this.appDomainName = value;
                this.appDomainNameInitialized = true;
            }
        }

        /// <summary>
        /// 获取当前进程的唯一标识符。
        /// </summary>
        [DataMember]
        public string ProcessId
        {
            get
            {
                this.EnsureProcessInfoInitialized();
                return this.processId;
            }
            set
            {
                this.processId = value;
                this.processInitialized = true;
            }
        }

        /// <summary>
        /// 获取当前进程的名称。
        /// </summary>
        [DataMember]
        public string ProcessName
        {
            get
            {
                this.EnsureProcessInfoInitialized();
                return processName;
            }
            set
            {
                this.processName = value;
                this.processInitialized = true;
            }
        }

        /// <summary>
        /// 获取当前托管线程的唯一标识符。 
        /// </summary>
        [DataMember]
        public string ThreadId
        {
            get
            {
                this.EnsureThreadIdInitialized();
                return this.threadId;
            }
            set
            {
                this.threadId = value;
                this.threadIdInitialized = true;
            }
        }

        /// <summary>
        /// 线程名称。
        /// </summary>
        [DataMember]
        public string ThreadName
        {
            get
            {
                this.EnsureThreadNameInitialized();
                return this.threadName;
            }
            set
            {
                this.threadName = value;
                this.threadNameInitialized = true;
            }
        }

        /// <summary>
        /// 获取当前线程的调用堆栈。
        /// </summary>
        [DataMember]
        public string StackTrace
        {
            get
            {
                EnsureStackTraceInitialized();
                return this.stackTrace;
            }
            set
            {
                this.stackTrace = value;
                this.stackTraceInitialized = true;
            }
        }

        /// <summary>
        /// 客户端 IP。
        /// </summary>
        [DataMember]
        public string ReferenceIP
        {
            get { return this.fromIP; }
            set { this.fromIP = value; }
        }

        /// <summary>
        /// 系统用户。
        /// </summary>
        [DataMember]
        public string AppUser
        {
            get { return this.appUser; }
            set { this.appUser = value; }
        }

        /// <summary>
        /// 扩展属性。
        /// </summary>
        public ExtendedPropertyCollection ExtendedProperties
        {
            get
            {
                if (this.extendedProperties == null)
                {
                    this.extendedProperties = new ExtendedPropertyCollection();
                }

                return this.extendedProperties;
            }
            set
            {
                this.extendedProperties = value;
            }
        }

        #endregion

        #region [ Methods ]

        /// <summary>
        /// 初始化跟踪时间信息。
        /// </summary>
        private void EnsureDateTimeInitialized()
        {
            this.DateTime = DateTime.Now;
        }

        /// <summary>
        /// 初始化跟踪时间信息。
        /// </summary>
        private void EnsureTimeStampInitialized()
        {
            this.Timestamp = DateTime.UtcNow.Ticks;
        }

        /// <summary>
        /// 初始化主机名。
        /// </summary>
        private void EnsureHostNameInitialized()
        {
            if (!this.hostNameInitialized)
            {
                this.HostName = EnvironmentHelper.MachineFullName;
            }
        }

        /// <summary>
        /// 初始化应用程序域信息。
        /// </summary>
        private void EnsureAppDomainNameInitialized()
        {
            if (!this.appDomainNameInitialized)
            {
                this.AppDomainName = EnvironmentHelper.AppDomainName;
            }
        }

        /// <summary>
        /// 初始化进程信息。
        /// </summary>
        private void EnsureProcessInfoInitialized()
        {
            if (!this.processInitialized)
            {
                this.ProcessId = EnvironmentHelper.ProcessId.ToString();
                this.ProcessName = EnvironmentHelper.ProcessName;

                this.processInitialized = true;
            }
        }

        /// <summary>
        /// 初始化线程代码信息。
        /// </summary>
        private void EnsureThreadIdInitialized()
        {
            if (!this.threadIdInitialized)
            {
                this.ThreadId = EnvironmentHelper.ThreadId.ToString();
            }
        }

        /// <summary>
        /// 初始化线程名称信息。
        /// </summary>
        private void EnsureThreadNameInitialized()
        {
            if (!this.threadNameInitialized)
            {
                this.ThreadName = EnvironmentHelper.ThreadName;
            }
        }

        /// <summary>
        /// 初始化堆栈信息。
        /// </summary>
        private void EnsureStackTraceInitialized()
        {
            if (!this.stackTraceInitialized)
            {
                if (this.Type < TraceEventType.Information)
                {
                    this.StackTrace = EnvironmentHelper.StackTrace;
                }
            }
        }

        /// <summary>
        /// 
        /// </summary>
        private void EnsureHostUserInitialized()
        {
            if (!this.hostUserInitialized)
            {
                this.HostUser = EnvironmentHelper.DomainUserName;
            }
        }

        #endregion
    }
}
